#ifndef DB8CAB28_610E_40ED_B7AC_52D6B4ED8CA0
#define DB8CAB28_610E_40ED_B7AC_52D6B4ED8CA0

#endif /* DB8CAB28_610E_40ED_B7AC_52D6B4ED8CA0 */

#pragma once
#include <iostream>
#include <vector>
#include <semaphore.h>

namespace ns_ring_queue
{
    //队列初始大小
    const int g_cap_default = 5;
    template <class T>
    class RingQueue
    {
    private:
        std::vector<T> ring_queue_;
        int cap_;
        //生产者空位置资源
        sem_t blank_sem_;
        //消费者关心数据资源
        sem_t data_sem_;
        
        //消费的位置
        int c_step_;
         //生产的位置
        int p_step_;

    public:
        RingQueue(int cap = g_cap_default)
            : ring_queue_(cap)
            , cap_(cap)
        {
            //信号量初始化
            sem_init(&blank_sem_, 0, cap);
            sem_init(&data_sem_, 0, 0);

            c_step_ = p_step_ = 0;
        }
        ~RingQueue()
        {
            //信号量销毁
            sem_destroy(&blank_sem_);
            sem_destroy(&data_sem_);
            
        }

        void Push(const T &in)
        {
            //申请信号量 P操作
            sem_wait(&blank_sem_);
            //放到到生产的位置
            ring_queue_[p_step_] = in;
            //释放信号量 消费者来消费
            sem_post(&data_sem_);
   
            p_step_++;
            //满了重新开始 环状
            p_step_ %= cap_;
        }

        void Pop(T *out)
        {
            //等数据消费
            sem_wait(&data_sem_);
            *out = ring_queue_[c_step_];
            sem_post(&blank_sem_);

            c_step_++;
            c_step_ %= cap_;
        }
    };
}